package com.fastbird.scio.util;

import com.fastbird.ml.PredictRequest;
import com.fastbird.ml.ScioModelImpl;
import com.google.gson.Gson;

//import org.apache.commons.io.output.*;

import java.io.ByteArrayOutputStream;
import java.security.SecureRandom;
import java.util.*;
import java.io.*;
/**
 * Created by yangguo on 2017/1/16.
 */
public class ScioModelSuit {
    public static class Bean{
        private double id;

        public double getId() {
            return id;
        }

        public void setId(double id) {
            this.id = id;
        }

        public long getTimestamp() {
            return timestamp;
        }

        public void setTimestamp(long timestamp) {
            this.timestamp = timestamp;
        }

        private long timestamp;

    }
    public static void createScioModel()throws Exception{
        String featureFile="C:\\Users\\wyd\\Desktop\\f1\\features.csv";//lable->features
        String xMeanFeatureFile="C:\\Users\\wyd\\Desktop\\f1\\xMeanFeature.csv";//lable->xmean;
        String yMeanFeatureFile="C:\\Users\\wyd\\Desktop\\f1\\yMeanFeature.csv";//lable->yFeature
        String boundFeatureFile="C:\\Users\\wyd\\Desktop\\f1\\bounds.csv";//lable->[max,min]
        String save="C:\\Users\\wyd\\Desktop\\f1\\scio.model.json";
        Map<String,double[]> features1=new HashMap<String, double[]>();
        //java.io.FileInputStream feature1=new java.io.FileInputStream(featureFile);
        //FileReader reader1=new FileReader(featureFile);
       // BufferedReader br1=new BufferedReader(reader1);

        InputStreamReader isr1 = new InputStreamReader(new FileInputStream(featureFile), "GBK");
        BufferedReader br1 = new BufferedReader(isr1);

        String str=null;
        String[] buffer=null;
        while((str=br1.readLine())!=null){
            buffer=str.split(",");
            if(buffer.length>1) {
                String[] feature = new String[buffer.length - 1];
                System.arraycopy(buffer, 1, feature, 0, buffer.length - 1);
                features1.put(buffer[0], toDouble(feature));
            }
        }

       // BufferedReader br2=new BufferedReader(new FileReader(xMeanFeatureFile));
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream(xMeanFeatureFile), "GBK");
        BufferedReader br2 = new BufferedReader(isr2);
        Map<String,double[]> xMeanFeature=new HashMap<String, double[]>();
        while((str=br2.readLine())!=null){
            buffer=str.split(",");
            if(buffer.length>1){
                String[] feature = new String[buffer.length - 1];
                System.arraycopy(buffer, 1, feature, 0, buffer.length - 1);
                xMeanFeature.put(buffer[0], toDouble(feature));
            }
        }
//        String[] xmean=br2.readLine().split(",");


        //br2=new BufferedReader(new FileReader(yMeanFeatureFile));
        InputStreamReader isr3 = new InputStreamReader(new FileInputStream(yMeanFeatureFile), "GBK");
        BufferedReader br3 = new BufferedReader(isr3);
        Map<String,Double> feature2=new HashMap<String, Double>();
        while((str=br3.readLine())!=null){
            System.out.println(str);
            buffer=str.split(",");
            feature2.put(buffer[0],toDouble(buffer[1]));
        }
        //BufferedReader br3=new BufferedReader(new FileReader(boundFeatureFile));
        InputStreamReader isr4 = new InputStreamReader(new FileInputStream(boundFeatureFile), "GBK");
        BufferedReader br4 = new BufferedReader(isr4);
        Map<String,double[]> boundFeatures=new HashMap<String, double[]>();
        while((str=br4.readLine())!=null){
            buffer=str.split(",");
            String[] feature=new String[2];
            System.arraycopy(buffer,1,feature,0,buffer.length-1);
            boundFeatures.put(buffer[0],toDouble(feature));
        }


        Map<String,Object> res=new HashMap<String,Object>();
        res.put("name","酒糟模型"); //玉米蛋白粉模型
        res.put("id",UUID.randomUUID().toString());
        res.put("version","1.0.0");
        res.put("xMeans",xMeanFeature);
        res.put("yMeans",feature2);
        res.put("features",features1);
        res.put("bounds",boundFeatures);

//        List<ScioModelImpl.AttributeFeature> attributes=new ArrayList<ScioModelImpl.AttributeFeature>();
//        for(Map.Entry<String,String> entry:feature2.entrySet()){
//            ScioModelImpl.AttributeFeature attribute=new ScioModelImpl.AttributeFeature();
//            String name=entry.getKey();
//            String unit="";
//            int index=name.indexOf("(");
//            String _name=name;
//            if(index>-1&&index<name.length()){
//                String[] t=name.split("\\(");
//                _name=t[0];
//                unit=t[1].replace("\\)","");
//            }
//            attribute.setName(_name);
//            attribute.setUnit(unit);
//            attribute.setYmean(toDouble(entry.getValue()));
//            attribute.setFeature(toDouble(features1.get(name)));
//            attributes.add(attribute);
//        }
//        scioModel.setAttributeFeatures(attributes);
//        scioModel.setxMeanVector(toDouble(xmean));
        Gson gson=new Gson();

        String json=(gson.toJson(res));
        FileOutputStream out=new FileOutputStream(save);
        out.write(json.getBytes());
        out.close();
    }
    public static Double toDouble(String value){
        return Double.parseDouble(value);
    }
    public static double[] toDouble(String[] values){
        double[] result=new double[values.length];
        for (int index=0;index<values.length;index++){
            result[index]=toDouble(values[index]);
        }
        return result;
    }

    public static void main(String[] args) throws Exception{

        String modelFile="C:\\Users\\wyd\\Desktop\\f\\scio.model.json";
//        java.io.InputStream instream=new java.io.FileInputStream(modelFile);
//        byte[] temp=new byte[1024];
//        ByteArrayOutputStream bufferStream=new ByteArrayOutputStream();
//        int length=0;
//        while((length=instream.read(temp))>=0){
//            bufferStream.write(temp,0,length);
//        }

//        Gson gson=new Gson();
//        Type type=new TypeToken<Map<String,Object>>(){}.getType();
//        Map<String,Object> coefficiens=gson.fromJson(new String(bufferStream.toByteArray(),"utf-8"),type);
//        System.out.println();
//
//
//                Map<String,Object> map=(LinkedTreeMap)coefficiens.get("features");//.getClass().getName());
//        List<Double> obj=(List<Double>)map.get("蛋白");
//        System.out.println(obj.getClass().getName()+","+obj.size());
//        ScioModelImpl model=new ScioModelImpl(new java.io.File(modelFile));
//
//        double[] t=new double[100];
//        Random rand=new SecureRandom();
//        for(int idx=0;idx<t.length;idx++){
//            t[idx]=rand.nextDouble();
//        }
//        System.out.println(model.toString());
//        createScioModel();
        String save="C:\\Users\\wyd\\Desktop\\f1\\scio.model.json";
        createScioModel();
        ScioModelImpl scioModel=new ScioModelImpl(new File(save));
        System.out.println(scioModel);
        test(scioModel);


//        ScioModelImpl model= ScioModelImpl.builderScioModel(loadModelCoefficient(new FileInputStream(save)));
//        System.out.println(model.toString());


    }
    private static String loadModelCoefficient(InputStream instream)throws IOException{
        byte[] temp=new byte[1024];
        ByteArrayOutputStream bufferStream=new ByteArrayOutputStream();
        int length=0;
        while((length=instream.read(temp))>=0){
            bufferStream.write(temp,0,length);
        }
        return new String(bufferStream.toByteArray(),"utf-8");

    }
    public void test1(){
        SortedSet<Bean> sortedSet = new TreeSet<Bean>(new Comparator<Bean>() {
            @Override
            public int compare(Bean o1, Bean o2) {
                return (o1.getId() - o2.getId()) >= 0 ? 1 : -1;
            }
        });

        SecureRandom rand = new SecureRandom();
        Bean b;
        for (int idx = 0; idx < 100; idx++) {
            b= new Bean();
            b.setId(rand.nextDouble());
            b.setTimestamp(rand.nextLong());
            sortedSet.add(b);
        }
        Iterator<Bean> bs=sortedSet.iterator();
        while (bs.hasNext()){
            b=bs.next();
            System.out.println(b.getId()+","+b.getTimestamp());
        }
    }
    public static void test(ScioModelImpl model) {
        java.util.List<PredictRequest> samples = new ArrayList<PredictRequest>();
        double[] baseLight;
        double[] series;
        double[] noLight;

        int seed = 100;
        Random rand = new Random(seed);
        for (int outIdx = 0; outIdx < 100; outIdx++) {
            baseLight = new double[100];
            series = new double[100];
            noLight = new double[100];

            for (int innerIdx = 0; innerIdx < 100; innerIdx++) {
                baseLight[innerIdx] = rand.nextDouble();
                series[innerIdx] = rand.nextDouble();
                noLight[innerIdx] = rand.nextDouble();
            }
            PredictRequest bean = new PredictRequest();
            bean.setBaseLightSeries(baseLight);
            bean.setNoLightSeries(noLight);
            bean.setSeries(series);
            samples.add(bean);
        }

        PredictRequest _bean = new PredictRequest();
        double[] _series = {51824.6, 51856, 51887.8, 51921.2, 51955.2, 51987.8, 52020.2, 52052.8, 52086.4, 52119.2, 52154.2, 52191.2, 52227.6, 52262, 52296, 52330, 52361.6, 52391.6, 52421, 52447.8, 52469.2, 52487.2, 52504.8, 52519.6, 52530.4, 52540.6, 52551.8, 52560, 52567.4, 52575.2, 52581.2, 52589, 52597.6, 52604.6, 52614, 52625, 52632.8, 52637.2, 52644.6, 52651.4, 52657.8, 52666.2, 52679.2, 52692.4, 52707, 52721.6, 52736.2, 52751.2, 52765.4, 52779.8, 52797.8, 52817.2, 52837.8, 52860, 52881.4, 52899.6, 52919.4, 52936, 52950.4, 52967, 52986.6, 53002, 53018.4, 53037, 53056.2, 53072.2, 53089.4, 53111, 53134.2, 53154.6, 53179.4, 53207.2, 53232.8, 53258.4, 53287.8, 53318.6, 53350.2, 53383.4, 53416, 53451.6, 53483.4, 53514, 53548.4, 53584, 53617.2, 53651.6, 53688.8, 53721.6, 53757.8, 53796.6, 53837.2, 53877, 53918.2, 53958.8, 54000, 54045.8, 54067.5, 54092.333333333336, 54119, 54148};
        _bean.setSeries(_series);
        double[] _baseLight = {52614.6, 52614.6, 52615.2, 52617, 52622.6, 52626, 52631.6, 52639.8, 52648, 52655.6, 52664.4, 52673.8, 52683.8, 52693.4, 52703.8, 52714.6, 52722.2, 52726.6, 52732.6, 52731.4, 52731, 52726.2, 52722.8, 52716.2, 52710.2, 52700.6, 52694, 52683.2, 52671.4, 52659.2, 52650.6, 52642.8, 52635.6, 52630, 52628.4, 52626.4, 52625.8, 52628.8, 52634.4, 52642, 52651, 52661.8, 52677.2, 52691.2, 52705.4, 52723.8, 52740.6, 52757, 52774, 52791.4, 52807, 52825.6, 52841, 52857.6, 52874.2, 52892.8, 52910.6, 52931, 52953, 52974.8, 52997, 53018.8, 53042.8, 53067, 53093.2, 53119.8, 53148.6, 53178, 53208, 53238.8, 53271.4, 53304.6, 53339.4, 53375, 53412.6, 53450, 53489.8, 53528.2, 53567.4, 53606.6, 53645.8, 53682.2, 53719.6, 53756.8, 53795.4, 53832.6, 53871.8, 53910.4, 53948.2, 53985.4, 54024.6, 54064, 54105.2, 54148, 54190.4, 54231, 54252.25, 54272.333333333336, 54291.5, 54309};
        _bean.setBaseLightSeries(_baseLight);
        double[] _noLight = {68.8, 67.6, 67.4, 67.6, 68.6, 69, 69.2, 68.6, 67.4, 67.4, 66.8, 66.8, 66.6, 68.6, 68.6, 69.2, 69.4, 69.6, 68.6, 68.6, 68.4, 68.4, 68.2, 68.4, 68, 68, 67.6, 67.8, 67.2, 67.8, 68, 69.4, 69.6, 69.8, 69.4, 68.2, 66.4, 65.8, 65.6, 66, 67.6, 68.4, 69, 68.6, 68.2, 67.4, 67.6, 67.6, 68.4, 69.8, 69.6, 70.4, 70, 70.2, 68.8, 70.2, 68.6, 70, 71.4, 71.8, 70.4, 70.8, 70, 68.2, 67.6, 67.6, 67.2, 66.4, 65.8, 66.8, 66.4, 67.2, 68.2, 68.6, 67.2, 67.4, 67.2, 65.2, 64.6, 64, 63.8, 62.6, 63.6, 62.8, 63.2, 63.4, 64.2, 63.8, 64, 63.4, 62.4, 61.6, 61.4, 62.4, 63.6, 65.6, 66.25, 67.66666666666667, 68.5, 71};
        _bean.setNoLightSeries(_noLight);
        samples.clear();
        samples.add(_bean);

        for (PredictRequest bean : samples) {
//            Map<String, Object> predict = model.predict(bean);
//            String t = "";
//            for (Map.Entry<String, Object> entry : predict.entrySet()) {
//                t += entry.getKey() + ":" + entry.getValue() + ";";
//            }
            Gson gson=new Gson();
            String json=gson.toJson(model.predict(bean));
            System.out.println(json);
        }
    }
}
